/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	RenderTechnique.h
*
*	Description -	RenderTechnique.
*
*	Comments	-
*
*	Modification History:
*			Name			   Date					Description
*			MrCodeSushi	-	08/31/2012	-	Creation of this file
**************************************************************************************/
#ifndef _PSX_RENDER_TECHNIQUE_H_
#define _PSX_RENDER_TECHNIQUE_H_

#include "PulseSTD.h"
#include "ResourcePoolItem.h"
#include "StoragePool.h"
#include "RenderPass.h"
#include "Array.h"
#include "String.h"

namespace Pulse
{
	typedef UINT8 TechniquePriority;

	struct RenderTechniqueDesc : public BaseResDesc
	{
	public:

		void SetToLoad( const CHAR *pFilename ) { m_filename = pFilename; }

		virtual const ResourceCode GetType( void ) const { return ResourceCode( EResource::VIDEO, EVideoResource::TECHNIQUE ); }
		
		String m_filename;
	};

	struct EffectRegister
	{
		UINT16				effectID;
		TechniquePriority	priority;
	};

	class RenderTechnique : public IResourcePoolItem
	{
	public:

		virtual ~RenderTechnique( void );

		// These defines the base interface for all derived resources
		virtual BOOL CreateResource( BaseResDesc *pDesc );
		virtual BOOL DestroyResource( void );
		virtual BOOL LoadResource( void );				
		virtual BOOL UnloadResource( void );

		virtual const ResourceCode GetType( void ) const { return ResourceCode( EResource::VIDEO, EVideoResource::TECHNIQUE ); }

		RenderTechniqueDesc * GetDescription( void ) { return &m_desc; }

	public:

		RenderPass * GetRenderPass( UPOS_T index );

		SIZE_T GetNumRenderPasses( void ) { return m_renderPasses.GetSize(); }

		void AddEffectRegister( EffectRegister *pRegister );

		EffectRegister * GetEffectRegisters( void );

		EffectRegister * GetEffectRegister( UPOS_T index );

		const SIZE_T GetNumEffectRegisters( void ) const { return m_effectRegisters.GetSize(); }

	private:

		PSX_MakeStoragePoolFriend( RenderTechnique );

		RenderTechnique( void );

		EErrorCode::Type Initialize( void );

		void Cleanup( void );

	private:

		// File parsing methods
		EErrorCode::Type ProcessTechnique( XMLElementPtr pElem );

		EErrorCode::Type ProcessEffectRegisters( XMLElementPtr pElem );

		EErrorCode::Type ProcessRequirements( XMLElementPtr pElem, RenderPass *pPass );

		EErrorCode::Type ProcessRenderPasses( XMLElementPtr pElem );

		EErrorCode::Type ProcessRenderStates( XMLElementPtr pElem, RenderPass *pNewPass );

	private:

		friend EffectsLibrary;

		typedef Array<RenderPass*> PassList;
		typedef Array<EffectRegister> EffectRegisterList;


		RenderTechniqueDesc		m_desc;
		EffectRegisterList		m_effectRegisters;
		PassList				m_renderPasses;
	};
}

#endif /* _PSX_RENDER_TECHNIQUE_H_ */
